Skip to content

Feat(notifications): What's New — featured item hero + also-new accordion#6

Draft
avivu wants to merge 27 commits into
mainfrom
feature/whats-new-featured-item
Draft

Feat(notifications): What's New — featured item hero + also-new accordion#6
avivu wants to merge 27 commits into
mainfrom
feature/whats-new-featured-item

Conversation

@avivu

@avivu avivu commented Jun 27, 2026

Copy link
Copy Markdown
Owner

Summary

  • Adds a featured item hero layout at the top of the What's New drawer — large image, title, optional plan chip overlay, and CTA button
  • Adds a collapsed accordion section for all non-featured items, each with expand/collapse (chevron icon) and a per-item unread dot indicator
  • The divider above the collapsed list accepts an optional listLabel field on the featured notification — plain divider is rendered when omitted
  • Badge (admin bar + editor app bar) shows the unread count and decrements per item via a e-notification-item-seen window event
  • seenItemIds state is lifted to WhatsNew so it survives drawer close/reopen within a session
  • initialHasUnread flag (captured once at page load from PHP) suppresses unread dots after a page refresh when there are no unread items
  • Featured hero items (and all items when no featured exist) are auto-marked as seen on drawer open so the badge clears correctly
  • PHP: exposes unread_count (integer) alongside is_unread (boolean) in the JS config; private helper eliminates duplication in Options

Test plan

  • Reset notifications via ?reset_notifications=1, reload — badge shows unread count
  • Open What's New drawer — featured item renders as hero with image; remaining items in collapsed list with blue dots
  • Expand a collapsed item — its dot disappears, badge decrements by 1
  • Close and reopen drawer — expanded items remain without dots; unexpanded still have dots
  • Expand all items — badge reaches 0 and disappears
  • Refresh page — no dots, no badge
  • Test with no featured items — all items render as original full-card layout, badge clears on drawer open
  • Test with listLabel on featured notification — divider shows the custom label text
  • Test without listLabel — divider is plain with no text
  • Test RTL — dots and chevrons align correctly using CSS logical properties

🤖 Generated with Claude Code

@avivu avivu force-pushed the feature/whats-new-featured-item branch from 9484ad8 to 3bda21d Compare June 27, 2026 16:00
avivu and others added 4 commits July 1, 2026 09:45
- Add featured item hero layout (image, title, chip overlay)
- Add "Also new" collapsed accordion list for non-featured items
- New WhatsNewItemCollapsed component with expand/collapse, chevron icon,
  and per-item unread dot (opacity-based, no layout shift)
- Lift seenItemIds state to WhatsNew so it survives drawer close/reopen
- Badge (bar button + editor app bar) decrements per item via
  e-notification-item-seen window event; no 9+ cap; corner-overlap position
- Auto-mark fully-visible items as seen (featured hero + all items when
  no featured exist) so badge clears correctly on drawer open
- initialHasUnread flag suppresses dots after page refresh with 0 unread

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace custom CSS keyframe animation and absolutely-positioned Box badge
with the MUI Badge component from @elementor/ui, matching the existing
design-system pattern. Also restore is_unread alongside unread_count in
the JS config to avoid breaking existing consumers.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- editor-v1.js: revert unread_count > 0 back to is_unread (restored in PHP config)
- whats-new-item.js: use insetInlineStart instead of left for RTL support

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Show 2-line clamped description in collapsed state (disappears when expanded)
- Increase item padding from py:1.5 to py:2 (16px) for better breathing room
- Align chevron to flex-start to match taller row height

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@avivu avivu force-pushed the feature/whats-new-featured-item branch from a681418 to 71f273e Compare July 1, 2026 06:45
avivu and others added 8 commits July 1, 2026 09:50
…lper

- options.php: extract private get_unread_notification_ids() to eliminate
  duplicated transient logic between has_unread_notifications/get_unread_count
- whats-new.js: wrap handleSeen with useCallback for stable reference;
  make setIsRead optional (default noop) so callers don't need to pass it
- whats-new-drawer-content.js: add PropTypes, remove eslint-disable, use
  useRef for seenItemIds to cleanly satisfy exhaustive-deps
- whats-new-item-collapsed.js: add PropTypes, remove eslint-disable
- whats-new-item.js: use MUI variant="h6" instead of hardcoded fontSize
- bar-button-notification.js: drop explicit setIsRead noop prop

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…Notification

BarButtonNotification no longer accepts defaultIsRead — badge state is
now driven by window.elementorNotifications.unread_count directly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add optional `listLabel` field to featured notifications that controls
the text shown in the divider above the collapsed items list.
When omitted, a plain divider is rendered with no label.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…isplay

wp_localize_script() converts all PHP values to strings, so unread_count: 0
becomes "0" in JS. Strict equality (0 === "0") returns false, causing the badge
to display "0" even when there are no unread notifications.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…isNew

Collapsing and re-expanding an item was calling onSeen again, causing the
badge to double-decrement. Fix in two places:
- handleSeen: only dispatch e-notification-item-seen when item wasn't already seen
- handleToggle: only call onSeen when the item is still unread (isNew)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@avivu avivu force-pushed the feature/whats-new-featured-item branch from 6c47038 to de68c17 Compare July 1, 2026 08:38
avivu and others added 15 commits July 2, 2026 08:44
…animation

When closing an expanded item, the description preview was appearing in the
header immediately (as expanded became false), while the image was still
visible inside the animating Collapse — causing a visual jump.

Fix: hide the preview on toggle and restore it only after onExited fires
(animation fully complete).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ransition

Instead of mounting/unmounting the description preview (which caused a height
jump when it appeared), always keep it in the DOM and transition opacity only.
Header height stays constant throughout the animation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Opacity-only approach left an invisible gap in the expanded header.
Also transition max-height and margin-top so the description takes
zero space when not shown.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Animating the preview in/out caused layout issues no matter the approach.
The title is sufficient for identification in collapsed state; the full
description is visible on expand.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Pass setIsOpen to WhatsNewItemCollapsed and add the same onClick handler
used in WhatsNewItem — clicking a '#'-prefixed CTA URL now closes the
drawer, consistent with the featured/regular item behaviour.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…24809] (elementor#36366)

<!-- CURSOR_AGENT_PR_BODY_BEGIN -->
## PR Type
- [x] Bugfix

## Summary

This PR can be summarized in the following changelog entry:

* Fix: WP Admin upgrade CTAs now use the correct `upgrade-one-wp-menu`
UTM instead of the legacy `wp-menu` UTM.

## Description

### Root cause

After the 10th birthday sale ended (ED-24386), non-sale upgrade paths in
Elementor core still pointed at the legacy short link
`https://go.elementor.com/pro-admin-menu/` (`utm_source=wp-menu`).

Editor One / wp-one-package already uses the correct link
(`https://go.elementor.com/go-pro-upgrade-one-wp-menu/` →
`utm_source=upgrade-one-wp-menu`), but core `Go_Pro_Promotion_Item` was
never updated when the legacy `go_elementor_pro` menu was removed
(ED-22438).

### Why only certain users?

| Path | URL source | UTM before fix |
|------|------------|----------------|
| Editor One upgrade submenu (`elementor-one-upgrade`) | wp-one-package
| Correct |
| Conversion banner (post-sale) | `Go_Pro_Promotion_Item::get_url()` |
**Old** |
| Legacy `go_elementor_pro` redirect / bookmarks |
`Go_Pro_Promotion_Item::get_url()` | **Old** |
| Connected One users (no upgrade submenu) | Other CTAs using core URL |
**Old** |

During the birthday sale, the conversion banner used a separate sale
URL, so the stale UTM resurfaced once `is_sale_time()` returned false.

### Changes

1. Update `Go_Pro_Promotion_Item::URL` to
`https://go.elementor.com/go-pro-upgrade-one-wp-menu/`
2. Extend `handle_external_redirects()` to handle both
`go_elementor_pro` and `elementor-one-upgrade`
3. Update admin JS/SCSS/tracking to support **both** legacy and Editor
One upgrade menu slugs (BC: Core can be lower than Pro)

### Backward compatibility

All client-side selectors and tracking now cover both paths:

- Legacy: `go_elementor_pro` under `#toplevel_page_elementor`
- Editor One: `elementor-one-upgrade` under
`#toplevel_page_elementor-home`

The shared `Go_Pro_Promotion_Item::URL` update fixes the UTM for both
paths, including conversion banner and legacy redirects.

### Note

Ticket requested PM approval from Doron Wolf Morrison before replacing
the UTM. This PR implements the UTM specified in ED-24809.

Fixes ED-24809

## Test instructions

1. On a free Elementor install with Editor One active, open WP Admin and
click **Upgrade** under the Elementor menu.
2. Confirm redirect goes to
`https://elementor.com/pro/?utm_source=upgrade-one-wp-menu&utm_medium=wp-dash&utm_campaign=gopro`.
3. On a page showing the conversion banner (post-sale), click **Upgrade
Now** and confirm the same UTM.
4. Visit `wp-admin/admin.php?page=go_elementor_pro` directly and confirm
the same redirect.
5. On a setup with legacy `go_elementor_pro` menu still present (older
Core), confirm styling, new-tab behavior, and tracking still work.

## Quality assurance

- [x] I have tested this code to the best of my abilities
- [ ] I have added unittests to verify the code works as intended
- [ ] Docs have been added / updated (for bug fixes / features)

<!-- CURSOR_AGENT_PR_BODY_END -->

<div><a
href="https://cursor.com/agents/bc-66e5f9ae-a795-4f23-b8b0-f4e47a43ccd0"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/open-in-web-light.png"><img
alt="Open in Web" width="114" height="28"
src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a>&nbsp;<a
href="https://cursor.com/background-agent?bcId=bc-66e5f9ae-a795-4f23-b8b0-f4e47a43ccd0"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img
alt="Open in Cursor" width="131" height="28"
src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a>&nbsp;</div>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Netanel Baba <Ntnelbaba@users.noreply.github.com>
…ED-24820] (elementor#36368)

## Summary
- Remove redundant per-event `app_type` from all editor event dispatch
payloads across legacy JS, packages, and onboarding analytics.
- Keep `appType: 'Editor'` registered via events-manager
`enableTracking()` as the single source of truth for editor context on
every event.
- `window_name` and `appTypes` config entries are unchanged — still used
for context-specific window identification.

## Test plan
- [x] `npm run test:jest -- --testPathPattern=editor-one-events-wpdash`
- [ ] Verify dispatched events in editor still include `appType: Editor`
via super property (no per-event `app_type`)
- [ ] Smoke-test publish dropdown, page list, onboarding, and
pro-install connect flows

Ref: [ED-24820](https://elementor.atlassian.net/browse/ED-24820)

Made with [Cursor](https://cursor.com)

[ED-24820]:
https://elementor.atlassian.net/browse/ED-24820?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
<!--start_gitstream_placeholder-->
### ✨ PR Description
## 1. Problem & Context

Consolidating analytics tracking by removing redundant per-event
`app_type` property across the codebase. The events-manager now handles
this as a super property (ED-24820), eliminating duplication.

## 2. What Changed (Where)

| File | Change |
|------|--------|
| onboarding events | Removed `app_type: 'editor'` from interface and
tracking payload |
| editor-app-bar hooks (5 files) | Removed `app_type` from event
payloads |
| editor-interactions, editor-controls tracking | Removed `app_type`
from base event properties |
| document delete command, editor-one-events | Removed `app_type` from
event data |
| pro-install events | Removed `app_type` from 4 tracking calls |
| test file | Updated assertions to expect payloads without `app_type` |

## 3. How It Works

Events previously included `app_type: 'editor'` at point of dispatch.
With this change, `app_type` is now injected by the events-manager as a
super property, applying uniformly across all events without repetition
in individual tracking calls.

## 4. Risks

Low risk—purely removes redundant payload fields already centralized in
events-manager. Verify events-manager super property implementation
correctly injects `app_type` to ensure backward compatibility in
analytics pipelines.

_Generated by LinearB AI and added by gitStream._
<sub>AI-generated content may contain inaccuracies. Please verify before
using.
💡 **Tip:** You can customize your AI Description using **Guidelines**
[Learn
how](https://docs.gitstream.cm/automation-actions/#describe-changes)</sub>
<!--end_gitstream_placeholder-->

Co-authored-by: Cursor <cursoragent@cursor.com>
…dgets\Utils [ED-24446] (elementor#36356)

Co-authored-by: ElementorBot <48412871+elementorbot@users.noreply.github.com>
## PR Checklist
<!-- 
Please check if your PR fulfills the following requirements:
**Filling out the template is required.** Any pull request that does not
include enough information to be reviewed in a timely manner may be
closed at the maintainers' discretion.
 -->
- [ ] The commit message follows our guidelines:
https://github.com/elementor/elementor/blob/master/.github/CONTRIBUTING.md


## PR Type
What kind of change does this PR introduce?
<!-- Please check the one that applies to this PR using "x" with no
spaces eg: [x]. -->
- [ ] Bugfix
- [ ] Feature
- [ ] Code style update (formatting, local variables)
- [ ] Refactoring (no functional changes, no api changes)
- [ ] Build related changes
- [ ] CI related changes
- [ ] Documentation content changes
- [ ] Other... Please describe:

## Summary

This PR can be summarized in the following changelog entry:

*

## Description
An explanation of what is done in this PR

*

## Test instructions
This PR can be tested by following these steps:

*

## Quality assurance

- [ ] I have tested this code to the best of my abilities
- [ ] I have added unittests to verify the code works as intended
- [ ] Docs have been added / updated (for bug fixes / features)

Fixes #

<!--start_gitstream_placeholder-->
### ✨ PR Description
## 1. Problem & Context

Automates cleanup of stale feature branches to reduce repository
clutter. Runs weekly on Mondays at 3 AM UTC with manual override
capability.

## 2. What Changed (Where)

- `.github/workflows/remove-stale-branches.yml`: New workflow that
identifies and removes branches not updated in 90+ days, excluding
active PRs and protected branches.

## 3. How It Works

Workflow builds exempt regex from open PR head refs plus version
patterns (main/master/semver), then delegates removal to
`fpicalausa/remove-stale-branches@v1.6.0` action. Operator notification
happens via stale comments before deletion window.

## 4. Risks

Token permissions sufficient but workflow runs unattended—misconfigured
regex or exempt pattern could delete important branches. Mitigation:
dry-run mode defaults to true for manual triggers; configurable grace
periods via repo vars.

_Generated by LinearB AI and added by gitStream._
<sub>AI-generated content may contain inaccuracies. Please verify before
using.
💡 **Tip:** You can customize your AI Description using **Guidelines**
[Learn
how](https://docs.gitstream.cm/automation-actions/#describe-changes)</sub>
<!--end_gitstream_placeholder-->

---------

Co-authored-by: ElementorBot <48412871+elementorbot@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…344] (elementor#36401)

## Summary
- `elementor-kit-mcp` fetched `GET /angie/v1/elementor-kit/schema`
**eagerly during MCP server construction** (before waiting for the Angie
SDK). Those `angie/v1/elementor-kit/*` routes are registered by the
Angie plugin, not core — so when Angie is inactive the call returned
`404 rest_no_route` on **every editor boot**, causing slow load / white
screen.
- Moved the schema fetch out of construction and into the schema
resource template's lazy `list` callback, mirroring the sibling
`elementor-v3-mcp` server (which does no eager network calls). The
schema is now fetched only once Angie connects and lists resources — the
exact case where the routes exist.
- With Angie inactive, `sdk.waitForReady()` never resolves, so the
server is never registered and the schema route is never called → no
404, no boot-time network cost.
- Added a unit test (`__tests__/elementor-kit-mcp-server.test.ts`)
asserting the schema endpoint is **not** hit during construction, and
**is** fetched lazily when resources are listed.

## Test plan
- [ ] `cd packages && npx jest core/elementor-kit-mcp` passes.
- [ ] **Angie inactive:** open the editor without the Angie plugin;
confirm (DevTools Network) no
`rest_route=/angie/v1/elementor-kit/schema` request fires on boot and no
`rest_no_route` 404 appears; editor loads without the
slow-load/white-screen delay.
- [ ] **Angie active:** open the editor with Angie active; exercise the
kit MCP flow (list kit schema tabs / update kit settings) and confirm it
still works (schema fetched lazily).

## Jira
[ED-24344](https://elementor.atlassian.net/browse/ED-24344)


[ED-24344]:
https://elementor.atlassian.net/browse/ED-24344?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
<!--start_gitstream_placeholder-->
### ✨ PR Description
## 1. Problem & Context

Schema fetch on server boot was causing 404 errors when Angie API wasn't
ready yet. Deferring it to lazy-load on first resource list request
avoids this.

## 2. What Changed (Where)

- **elementor-kit-mcp-server.ts**: Moved `getAvailableTabs()` call
inside `list()` callback; was executing synchronously at boot.
- **elementor-kit-mcp-server.test.ts**: Added test suite verifying
schema isn't fetched during construction, only on resource listing.

## 3. How It Works

Schema fetch now happens inside the `list` async callback (line 220)
instead of at module initialization. When a client requests available
resources, `getAvailableTabs()` executes and populates the resource
map—eliminating the premature 404.

## 4. Risks

None identified. Lazy loading is safer (defers external dependency call)
and test coverage validates both boot-time non-execution and lazy-load
execution paths.

_Generated by LinearB AI and added by gitStream._
<sub>AI-generated content may contain inaccuracies. Please verify before
using.
💡 **Tip:** You can customize your AI Description using **Guidelines**
[Learn
how](https://docs.gitstream.cm/automation-actions/#describe-changes)</sub>
<!--end_gitstream_placeholder-->
## PR Checklist
<!-- 
Please check if your PR fulfills the following requirements:
**Filling out the template is required.** Any pull request that does not
include enough information to be reviewed in a timely manner may be
closed at the maintainers' discretion.
 -->
- [ ] The commit message follows our guidelines:
https://github.com/elementor/elementor/blob/master/.github/CONTRIBUTING.md


## PR Type
What kind of change does this PR introduce?
<!-- Please check the one that applies to this PR using "x" with no
spaces eg: [x]. -->
- [ ] Bugfix
- [ ] Feature
- [ ] Code style update (formatting, local variables)
- [ ] Refactoring (no functional changes, no api changes)
- [ ] Build related changes
- [ ] CI related changes
- [ ] Documentation content changes
- [ ] Other... Please describe:

## Summary

This PR can be summarized in the following changelog entry:

*

## Description
An explanation of what is done in this PR

*

## Test instructions
This PR can be tested by following these steps:

*

## Quality assurance

- [ ] I have tested this code to the best of my abilities
- [ ] I have added unittests to verify the code works as intended
- [ ] Docs have been added / updated (for bug fixes / features)

Fixes #
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… expanded

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants